<?php

/**
 * IcibaDict是对iciba的网络词典接口的一层封装, 通过使用IcibaDict并调用相应地接口, 即可
 * 获得相应单词地iciba词典解释, 该解释被封装在一个数组中.
 *
 * <p>
 * 单词的释义的数组:
 * key => 单词本身;
 * ps => 单词的发音;
 * pron => 单词的音频文件地址;
 * pos => 单词的释义数组;
 * sent => 单词的示例数组.
 *
 * @author hutushen222
 * @version 1.0.0 2010-07-19
 */
class IcibaDict {

	/**
	 * IcibaDict的默认构造函数
	 */
	function IcibaDict() {

	}

	/**
	 * lookup为查询接口, 通过此接口传入一个单词, 即可获得该单词的词典解释.
	 *
	 * @param string $word -- 待查寻地单词
	 * @return $result -- 按一定格式组织的一个单词的数组
	 * 			如果单词无对应的释义则返回一个空数组 array().
	 */
	function lookup($word) {
		# 如果没有给定单词，返回null
		if (trim($word) == '') {
			return null;
		}

		# 将单词进行编码，使其满足URL的规范
		$word = rawurlencode($word);

		// iciba的查词接口
		$url = "http://dict-co.iciba.com/api/dictionary.php?w=".$word;
		// 获取iciba词典查询后返回的结果
		$content = file_get_contents($url);

		// 如果没有检测到单词地释义, iciba返回一个<dict>节点下为空的XML文件的字符串, 其长度为51
		if (strlen($content) === 51) {
			$this->result = array();
			return null;
		}

		// 如果返回的结果不为空
		# 将返回的字符串中的非XML标签的"<"和">"替换为"["和"]"
		$snippets = array();
		$matchtimes = preg_match('/<[\x{4e00}-\x{9fa5}]+>/iu', $content, $snippets);
		for ($i = 0; $i < count($snippets); $i++) {
			$snippets[$i] = str_replace('<', '[', $snippets[$i]);
			$snippets[$i] = str_replace('>', ']', $snippets[$i]);
		}
		for ($i = 0; $i < count($snippets); $i++) {
			$content = preg_replace('/<[\x{4e00}-\x{9fa5}]+>/iu', $snippets[$i], $content, 1);
		}

		// 将iciba返回的结果构造为XML Element对象
		$xml = new SimpleXMLElement($content) or die('format is wrong');

		// 处理获取地XML Element对象
		// $key代表单词本身 -- 如果XML文件中没有key元素,则$key为空字符串,可以使用empty函数判断
		$key = $xml->key;
		# 如果没有对应的key值，返回空
		if ($key == '') {
			return null;
		}
		// $ps代表单词的发音 -- 如果XML文件中没有ps元素,则$ps为空字符串,可以使用empty函数判断
		$ps = $xml->ps;
		// $pron代表单词的音频文件的地址  -- 如果XML文件中没有pron元素,则$pron为空字符串,可以使用empty函数判断
		$pron = $xml->pron;
		// 如果单词只有一个释义,则$pos为一普通变量,否则$pos为一数字索引数组
		$pos = $xml->pos;
		// 如果单词只有一个释义,则$acceptation为一普通变量,否则$acceptation为一数字索引数组,与$pos一一对应
		$acceptation = $xml->acceptation;
		//		// $sent是iciba词典给与的单词相关示例
		//		$sent = $xml->sent;

		// 处理单词自身
		$this->result['key'] = $key;
		// 处理单词的发音
		$this->result['ps'] = $ps;
		// 处理单词的音频文件地址
		$this->result['pron'] = $pron;
		// 处理单词的释义, 所有的都当作数组处理
		$poses = array();
		for ($i = 0; $i < count($pos); $i++) {
			$poses[] = $pos[$i]." ".$acceptation[$i]."; \n";
		}
		$this->result['pos'] = $poses;

		//		// 处理单词的例句, 所有的都当作数组处理
		//		$sents = array();
		//		foreach ($sent as $value) {
		//			$sents[] = $value;
		//		}
		//		$this->result['sent'] = $sents;

		// 返回结果
		# 当单词和释义都为空的时候，返回null
		return $this->result;
	}


	# 翻译返回的结果
	private $result = array();

}
############################################################################
# 测试部分 #
##########
//$iciba = new IcibaDict();
//$result = $iciba->lookup('lili');
//echo "<pre>";
//echo var_dump($result)."<hr>";
//echo "</pre>";

# who 如果单词只有一个释义，则pos, acceptation不会构成数组
# lili 没有key等元素
# gigi 会出错， 无法生成有效的xml文件, 这种情况使用特殊处理机制
# bbbbbbbb 单词不存在, 则返回一个空的XML文件, 只有头和跟节点, 根节点为空
# contrast 应该具有多个读音的， 但是iciba并没有表示出来
############################################################################

?>